<template>
  <div style="margin: 10px;height: 100vh"  v-loading="spinning">
    <el-row>
      <el-col :span="24">
        <el-row :gutter="24">

          <el-col :span="15">
            <el-button type="primary" @click="menuSaveOrUpdateShow('')" plain>
              新增
            </el-button>
            <el-tooltip
                effect="dark"
                :content="defaultExpandAll?'折叠':'展开'"
            >
              <el-button type="info" @click="defaultExpandAll=!defaultExpandAll"  plain>
                <el-icon>
                  <Sort/>
                </el-icon>
              </el-button>
            </el-tooltip>
          </el-col>
          <el-col :span="9">

            <div class="ml-4" style="position: relative;
    float: right;">
              <el-tooltip
                  effect="dark"
                  content="刷新"
              >
                <el-button circle @click="getMenuList">
                  <el-icon :class="{'is-loading':spinning}">
                    <Refresh/>
                  </el-icon>
                </el-button>
              </el-tooltip>
            </div>

          </el-col>
        </el-row>
      </el-col>
      <el-col :span="24">
        <el-container>
          <el-main>
        <el-table stripe
                  :data="tableData"
                  style="width: auto" header-row-class-name="etable" height="90vh"
                  row-key="id"
                  border
                  :highlight-current="true"
                  :default-expand-all="false"
                  :expand-row-keys="defaultExpandAll?directoryIds:[]"
                  :tree-props="{ children: 'childMenuListVOs'}"
        >
          <el-table-column prop="menuName" label="菜单名称"/>
          <el-table-column prop="menuIcon" label="图标">
            <template #default="scope" >
              <el-icon v-if="scope.row.menuIcon!=''">
                <component :is="scope.row.menuIcon"/>
              </el-icon>
            </template>
          </el-table-column>
          <el-table-column prop="menuSort" label="排序"/>
          <el-table-column label="类型">
            <template #default="scope">
              <el-tag :type="scope.row.menuTypeTagEnumBean.style.type" round>
                {{ scope.row.menuTypeTagEnumBean.msg }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="menuRoute" label="路由"/>
          <el-table-column prop="menuPower" label="权限"/>
          <el-table-column prop="menuInfoUrl" label="页面初始化地址"/>

          <el-table-column label="状态">
            <template #default="scope">
              <el-tag :type="scope.row.menuStateTagEnumBean.style.type" round>
                {{ scope.row.menuStateTagEnumBean.msg }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作">
            <template #default="scope">
              <el-button
                  size="small"
                  style="margin-right: 2px"
                  link type="success"
                  :icon="Edit"
                  @click=" menuSaveOrUpdateShow(scope.row.id)"
              >
                修改
              </el-button>


              <el-popconfirm v-if="scope.row.menuState=='NORMAL'"
                             :title="'确定要停用【'+scope.row.menuName+'】本菜及子菜单'"
                             @confirm="updateMenuState(scope.row.id)"
                             @cancel="updateCancel"
                             confirm-button-text="确认"
                             cancel-button-text="取消"
              >
                <template #reference>
                  <el-button link type="warning" :icon="TurnOff" size="small"
                             style="margin-right: 2px">停用
                  </el-button>
                </template>
              </el-popconfirm>


              <el-popconfirm

                  v-if="scope.row.menuState=='STOP'"
                  :title="'确定要启用【'+scope.row.menuName+'】本菜单'"
                  confirm-button-text="确认"
                  cancel-button-text="取消"
                  @confirm="updateMenuState(scope.row.id)"
                  @cancel="updateCancel"
              >
                <template #reference>
                  <el-button link type="primary" :icon="Open" size="small"
                             style="margin-right: 2px">启用
                  </el-button>
                </template>
              </el-popconfirm>


            </template>


          </el-table-column>

        </el-table>
          </el-main>
        </el-container>
      </el-col>

    </el-row>


  </div>


  <el-dialog v-model="saveOrUpdateVisible" :title="saveUpdateTitle" width="800px" >
    <el-form :model="MenuSaveOrUpdateParam" label-width="auto" style="max-width: 800px"
             ref="MenuSaveOrUpdateRef"
             :rules="MenuSaveOrUpdateRules"
    >
      <el-form-item label="菜单类型" prop="menuType">
        <el-radio-group v-model="MenuSaveOrUpdateParam.menuType"  >
          <el-radio-button label="目录" value="DIRECTORY"  :disabled="updateMenuId!=''&& MenuSaveOrUpdateParam.menuType!='DIRECTORY'"/>
          <el-radio-button label="菜单" value="MENU" :disabled="updateMenuId!=''&& MenuSaveOrUpdateParam.menuType!='MENU'"/>
          <el-radio-button label="按钮" value="BUTTON" :disabled="updateMenuId!=''&& MenuSaveOrUpdateParam.menuType!='BUTTON'"/>
        </el-radio-group>
      </el-form-item>
      <el-form-item :label="pidLabel" prop="pid"  v-if="pidLabel!=''">
        <el-tree-select
            v-if="MenuSaveOrUpdateParam.menuType=='BUTTON'"
            v-model="MenuSaveOrUpdateParam.pid"
            :data="notBottonListVOS"
            check-strictly
            :render-after-expand="false"
            node-key="id"
            style="width: 100%;background-color: #ccccff"
            :props="{children: 'childMenuListVOs', label: 'menuName', id: 'id'}"
            clearable
        />
        <el-tree-select
            v-if="MenuSaveOrUpdateParam.menuType=='MENU'"
            v-model="MenuSaveOrUpdateParam.pid"
            :data="directoryListVOS"
            check-strictly
            :render-after-expand="false"
            node-key="id"
            style="width: 100%;background-color: #ccccff"
            :props="{label: 'menuName', id: 'id'}"
            clearable
        />
      </el-form-item>


      <el-form-item :label="menuNameLabel" prop="menuName">
        <el-input v-model="MenuSaveOrUpdateParam.menuName" clearable/>
      </el-form-item>

      <el-form-item label="菜单图标" prop="menuIcon"   v-if="MenuSaveOrUpdateParam.menuType!='BUTTON'">
                <el-button :icon="MenuSaveOrUpdateParam.menuIcon"  @click="visible = true" />
        <el-dialog
            v-model="visible"
            width="500"
            title="选择图标"
            append-to-body
        >
            <el-scrollbar height="400px" style="padding: 0;margin: 0">
              <el-button v-for="item in iconList" :icon="item" size="small" style="margin-left: 0" @click="selectIcon(item)">
              </el-button>
            </el-scrollbar>
        </el-dialog>



      </el-form-item>
      <el-form-item label="菜单路由" prop="menuRoute"  v-if="MenuSaveOrUpdateParam.menuType=='MENU'">
        <el-input v-model="MenuSaveOrUpdateParam.menuRoute" clearable/>
      </el-form-item>
      <el-form-item label="菜单权限标识" prop="menuPower" v-if="MenuSaveOrUpdateParam.menuType!='DIRECTORY'">
        <el-input v-model="MenuSaveOrUpdateParam.menuPower" clearable/>
      </el-form-item>

      <el-form-item label="页面初始化地址" prop="menuInfoUrl" v-if="MenuSaveOrUpdateParam.menuType=='MENU'">
        <el-input v-model="MenuSaveOrUpdateParam.menuInfoUrl" clearable/>
      </el-form-item>

      <el-form-item label="排序" prop="menuSort">
        <el-input-number v-model="MenuSaveOrUpdateParam.menuSort" :min="1" :max="99"/>
      </el-form-item>

    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="primary" @click="saveSubmit(MenuSaveOrUpdateRef)" v-if="updateMenuId==''" :loading="spinning">添加
        </el-button>
        <el-button type="primary" @click="updateSubmit(MenuSaveOrUpdateRef)" v-if="updateMenuId!=''" :loading="spinning">修改
        </el-button>
        <el-button @click="saveOrUpdateVisible = false">取消</el-button>
      </div>
    </template>
  </el-dialog>

</template>

<script lang="ts" setup>
import {
  onMounted,
  ref,
  reactive,
  type Ref,
  type UnwrapRef,
  watch,
  getCurrentInstance
} from 'vue'

import request from "@/api/request";
import {MenuFromInfo, MenuSaveOrUpdateParam} from "@/views/sys/menu/menuInfo";

import {type FormInstance, type ElDialog, type FormRules, ElMessage} from "element-plus";
import {userSaveOrUpdateParam} from "@/views/sys/user/userInfo";
import type {TreeProps} from "element-plus/es/components/tree-v2/src/types";
import {Edit, Open, TurnOff} from "@element-plus/icons-vue";


const { appContext } = getCurrentInstance()
//获取图标列表
const icons=appContext.config.globalProperties.$icons
//数据加载
let spinning = ref<boolean>(false);
//图标选择弹窗
let visible = ref<boolean>(false);
//弹窗菜单名
let menuNameLabel = ref("名称");
//弹窗上级菜单名
let pidLabel = ref("");
//图表集合
let iconList=ref([]);

//监听弹窗菜单类型变化
watch(()=>JSON.parse(JSON.stringify(MenuSaveOrUpdateParam.value)), (newValue, oldValue) => {
  if(newValue.menuType!=oldValue.menuType){
    pidLabel.value='';
    if(newValue.menuType=='DIRECTORY'){
      menuNameLabel.value='目录名称';
    }else if(newValue.menuType=='MENU'){
      menuNameLabel.value='菜单名称';
      pidLabel.value='所属目录';
      MenuSaveOrUpdateParam.value.pid="";
    }else if(newValue.menuType=='BUTTON'){
      menuNameLabel.value='按钮名称';
      pidLabel.value='所属菜单';
      MenuSaveOrUpdateParam.value.pid="";
      MenuSaveOrUpdateParam.value.menuIcon="CoffeeCup";
    }
  }
}, {
  deep: true, // 如果你需要深度观察对象属性，则设置为true
  flush: 'post', // 默认值是'pre', 如果需要在DOM更新后触发，则设置为'post'
});

//弹窗选择图标
function selectIcon(item:string){
  MenuSaveOrUpdateParam.value.menuIcon=item;
  visible.value=false;
}

//列表默认折叠
let defaultExpandAll = ref(false);

let notBottonListVOS = ref<TreeProps[]>([]);
let directoryListVOS = ref<TreeProps[]>([]);
const tableData: Ref<UnwrapRef<any[]>> = ref([]);

let directoryIds = ref([]);
let bottonIds = ref([]);
//页面加载
onMounted(() => {
  for (const [key, component] of Object.entries(icons)) {
    iconList.value.push(key)
  }
  getMenuList();
})





//列表加载
function getMenuList() {
  spinning.value = true;
  request.get('/sysMenu/menuListTree').then((res: any) => {
    spinning.value = false;
    if (res.code == '10000') {
      notBottonListVOS.value = res.data.notBottonListVOS;
      directoryListVOS.value = res.data.directoryListVOS;
      tableData.value = res.data.menuListVOS;
      directoryIds.value = res.data.directoryIds;

    } else {
      ElMessage.error(res.errorMessage);
    }
  }).catch((error) => {
    spinning.value = false;
  })
}


//修改的用户id
let updateMenuId = ref<string>("");
//添加修改是否可见弹窗
let saveOrUpdateVisible = ref<boolean>(false)
//弹窗标题
let saveUpdateTitle = ref<string>("添加菜单");

function menuSaveOrUpdateShow(id: string) {

  if (id == null || id == '') {
    MenuFromInfo(null)
    updateMenuId.value = "";
    saveUpdateTitle = ref("添加");
    saveOrUpdateVisible.value = true;
    console.log( MenuSaveOrUpdateParam.value)
  } else {

    request.get('/sysMenu/' + id).then((res: any) => {
      if (res.code == '10000') {
        updateMenuId.value = id;
        saveUpdateTitle.value = "修改";
        MenuFromInfo(res.data);
        saveOrUpdateVisible.value = true;
      } else {
        ElMessage.error(res.errorMessage);
      }
    }).catch((error) => {
      spinning.value = false;
    })
  }
}




const MenuSaveOrUpdateRef = ref<FormInstance>()

const pidCheck = (rule, value, callback) => {

  if(MenuSaveOrUpdateParam.value.menuType=='BUTTON'){
    if(value === undefined||value==''){
      callback(new Error('请选择所属菜单'))
    }else{
      notBottonListVOS.value.forEach((menuList, index) => {
          if(menuList.id==value&&menuList.menuType!='MENU'){
            callback(new Error('上级菜单不能选择为目录'))
          }
      });
      callback()
    }
  } else {
    callback()
  }

}

const menuInfoUrlCheck = (rule, value, callback) => {

  if(MenuSaveOrUpdateParam.value.menuType=='MENU'){
    if(value === undefined||value==''){
      callback(new Error('请填写页面初始化地址'))
    }else{

      request.get(value).then((res: any) => {
        spinning.value = false;
        if (res.code == '10000') {
          callback()
        } else {
          ElMessage.error(res.errorMessage);
          callback(new Error('页面初始化地址验证异常'))
        }
      }).catch((error) => {
        callback(new Error('页面初始化地址验证异常'))
      })

    }
  } else {
    callback()
  }

}

//添加修改验证
const MenuSaveOrUpdateRules = reactive<FormRules<MenuSaveOrUpdateParam>>({
  pid: [
    { validator:pidCheck, trigger: 'change'}
  ],
  menuInfoUrl: [
    { validator:menuInfoUrlCheck, trigger: 'change'}
  ],
  menuName: [
    {required: true, message: '请填写名称', trigger: 'blur'}
  ],
  menuSort: [
    {required: true, message: '请填写排序', trigger: 'blur'}
  ],
});




const saveSubmit = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid, fields) => {
    if (valid) {

      request.post('/sysMenu/', MenuSaveOrUpdateParam.value).then((res: any) => {

        saveOrUpdateVisible.value = false;
        if (res.code == '10000') {
          ElMessage.success("添加成功");

          saveOrUpdateVisible.value = false;
          getMenuList();
        } else {
          ElMessage.error(res.errorMessage);
        }
      }).catch((error) => {
        ElMessage.error(error)
      })

    } else {
      console.log('error submit!', fields)
    }
  })
}

//更新用户信息
const updateSubmit = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  console.log("1ok1")
  await formEl.validate((valid, fields) => {
    console.log("1ok")
    if (valid) {
      console.log("ok")
      request.put('/sysMenu/' + updateMenuId.value, MenuSaveOrUpdateParam.value).then((res: any) => {
        if (res.code == '10000') {
          ElMessage.success("修改成功");

          saveOrUpdateVisible.value = false;
          getMenuList();
        } else {
          ElMessage.error(res.errorMessage);
        }
      }).catch((error) => {
        ElMessage.error(error)
      })

    } else {
      console.log('error submit!', fields)
    }
  })
}


function updateMenuState(id: string) {

  request.put('/sysMenu/updateMenuState/' + id).then((res: any) => {
    spinning.value = false;
    // queryFormInlineSubmit.value=null;
    if (res.code == '10000') {
      ElMessage.success("变更成功");
      getMenuList();
    } else {
      ElMessage.error(res.errorMessage);
    }
  }).catch((error) => {
    spinning.value = false;
  })

}


//删除取消
const updateCancel = (e: MouseEvent) => {
};


</script>
